跳到主要内容

JVM 初级面试题

1、对象在哪块内存分配?

数组和对象在堆内存分配;某些对象没有逃逸出方法,可能被优化为在栈上分配

2、谈谈 JVM 中的常量池

JDK 1.8 开始

字符串常量池:存放在堆中,包括 String 对象执行 intern() 方法后存的地方、双引号直接引用的字符串

运行时常量池:存放在方法区,属于元空间,是类加载后的一些存储区域,大多数是类中 constant_pool 的内容

类文件常量池:constant_pool,JVM 定义的概念

3、谈谈动态年龄判断

这里涉及到 -XX:TargetSurvivorRatio 参数,Survivor 区的目标使用率默认 50,即 Survivor 区对象目标使用率为 50%。

Survivor 区相同年龄所有对象大小的总和 > (Survivor 区内存大小 * 这个目标使用率)时,大于或等于该年龄的对象直接进入老年代。

当然,这里还需要考虑参数 -XX:MaxTenuringThreshold 晋升年龄最大阈值

4、谈谈永久代

JDK 8 之前,Hotspot 中方法区的实现是永久代(Perm)

JDK 7 开始把原本放在永久代的字符串常量池、静态变量等移出到堆,JDK 8 开始去除永久代,使用元空间(Metaspace),永久代剩余内容移至元空间,元空间直接在本地内存分配。

5、JVM 有哪些运行时内存区域?

Java 8

The pc Register,程序计数器

Java Virtual Machine Stacks,Java 虚拟机栈

Heap,堆

Method Area,方法区

Run-Time Constant Pool,运行时常量池

Native Method Stacks,本地方法栈

6、运行时栈帧包含哪些结构?

局部变量表

操作数栈

动态连接

返回地址

附加信息

7、JVM 的内存模型是什么?

JVM 试图定义一种统一的内存模型,能将各种底层硬件以及操作系统的内存访问差异进行封装,使 Java 程序在不同硬件以及操作系统上都能达到相同的并发效果。它分为工作内存和主内存,线程无法对主存储器直接进行操作,如果一个线程要和另外一个线程通信,那么只能通过主存进行交换。

8、JVM 如何确定垃圾对象?